// ----------------------------------- 常量 ----------------------------------------------
/**
 * API常量
 */
var HOST = 'http://139.196.236.231:8070';
var api = {
	system:{
		checkUpdate:HOST+"/api/System/CheckUpdate",
	},
	user: {
		login: HOST + '/api/User/Login',
	},
};

var animation = {
	popIn: 'pop-in',
	popOut: 'pop-out',
	slideInRight: 'slide-in-right',
	slideOutRight: 'slide-out-right',
	slideInBottom: 'slide-in-bottom',
	slideOutBottom: 'slide-out-bottom',
}

/*
 * message常量
 */
var msg = {
	TITLE: 'zhaidangjia',
	NETWORK_IS_UNAVAILABLE: "网络异常，请检查您的网络设置",
	LOAD_DATA_FAIL: '数据加载失败，请稍后重试',
	AUTH_EXPIRED: '您的登录已过期，请重新登录',
};

// -------------------------- 最常用的方法 -----------------------------------
/*
 * 保存数据
 */
function cache(key, val) {
	if (key === 'clear') {
		window.localStorage.clear();
	} else if (val === null) {
		window.localStorage.removeItem(key);
	} else if (val) {
		window.localStorage[key] = val;
	} else {
		return window.localStorage[key];
	}
}

/*
 * 封装常用的打开窗口，一般只需传入url及id
 * 默认显示等待框，默认不自动显示
 */
function openPage(url, id, extraObj, styleObj, showObj, waitObj) {
	// id 默认为url
	id = id || url;
	// 暴力解决打开已存在的webview时发生的bug
	var targetPage = plus.webview.getWebviewById(id);
	if (targetPage) {
		// 方案1，杀掉旧的webview再打开新的webview
		plus.webview.close(targetPage, 'none');
		console.log(id + " is exist, killed it.");

		// 方法2，触发webview的plusReady事件，这种方法还不太妥当
		//		if (extraObj){
		//			mui.extend(targetPage,extraObj);
		//		}
		//		mui.fire(targetPage,'plusready');
		//		console.log(id+" is exist, recalled it.");
		//		return;
	}

	showObj = showObj || {
		autoShow: false
	};
	waitObj = waitObj || {
		autoShow: true
	}; // 默认显示等待框

	doopen();

	function doopen() {
		if (plus.webview.getWebviewById(id)) {
			setTimeout(doopen, 100);
		} else {
			mui.openWindow({
				url: url,
				id: id,
				styles: styleObj,
				extras: extraObj,
				show: showObj,
				waiting: waitObj,
			})
		}

	}
}

function showPage(wv, aniShow, closeWaiting, duration) {
	if (tool.isEmptyVal(wv)) {
		console.log('webview为空');
		return;
	}
	aniShow = aniShow || animation.popIn;
	duration = duration || (mui.os.ios ? 300 : 250); // pop-in动画在ios平台上300ms为佳，在android平台上250为佳
	wv.show(aniShow, duration);
	closeWaiting = typeof(closeWaiting) === "undefined" ? true : closeWaiting; // 默认要关闭
	if (closeWaiting) plus.nativeUI.closeWaiting();
}

// ------------------------------------- 通用方法 -----------------------------
/*
 * 工具类
 */
var tool = {
	isEmptyVal: function(val) {
		if (val === null || typeof(val) === 'undefined' || val === '')
			return true;

		return false;
	},
	isFunction: function(f) {
		return Object.prototype.toString.call(f) === "[object Function]";
	},
	isObject: function(o) {
		return Object.prototype.toString.call(o) === "[object Object]";
	},
	isString: function(s) {
		return Object.prototype.toString.call(s) === "[object String]";
	},
	isNodeList: function(s) {
		return Object.prototype.toString.call(s) === "[object NodeList]";
	},
	isInArray: function(a, obj) {
		var i = a.length;
		while (i--) {
			if (a[i] === obj) {
				return true;
			}
		}
		return false;
	},
	isEmail: function(val) {
		return /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(val);
	},
};

var app = {
	initTipMask:function (key) {
		var tipMask = document.getElementById("tipMask");
		mui('.tip-line').css('width',(window.innerWidth-72)/2+'px');
		if (!cache(key)) {
			tipMask.style.display = 'block';
		}
//		tipMask.style.display = 'block';
		this.on('.tip-button',function () {
			var tag = this.dataset.tag;
			tipMask.style.display = 'none';
			if (tag === 'hide') {
				cache(key,'true');
			}
		})
	},
	showLoading: function() {
		if (document.querySelector('.app-loading')) {
			document.querySelector('.app-loading').style.display = 'table';
		} else {
			var fragment = document.createDocumentFragment();
			var loading = document.createElement("div");
			loading.className = 'app-loading mui-fullscreen';
			var div = document.createElement('div');
			var span = document.createElement('span');
			span.innerText = 'Loading';
			span.className = 'three-quarters-loader';
			div.appendChild(span);
			loading.appendChild(div);
			fragment.appendChild(loading);
			loading.style.display = 'table';
			document.body.appendChild(fragment);
		}
	},
	hideLoading: function() {
		var loading = document.querySelector('.app-loading');
		if(loading)
			loading.style.display = 'none';
	},
	map: function(elements, callback) {
		var value, values = [],
			i, key, len;
		if (typeof elements.length === 'number') { //TODO 此处逻辑不严谨，可能会有Object:{a:'b',length:1}的情况未处理
			for (i = 0, len = elements.length; i < len; i++) {
				value = callback(elements[i], i);
				if (value != null) values.push(value);
			}
		} else {
			for (key in elements) {
				value = callback(elements[key], key);
				if (value != null) values.push(value);
			}
		}
		return values.length > 0 ? [].concat.apply([], values) : values;
	},
	/*
	 * 封装常用的注册事件
	 * element可为元素、元素列表或css选择器
	 * type可选，默认为tap
	 */
	on: function(element, type, evt) {
		// element参数必须传入
		if (!element) {
			return;
		}

		// 确定element
		if (tool.isString(element)) {
			element = document.querySelectorAll(element);
		}

		// 确定type和evt
		if (tool.isFunction(type)) {
			evt = type;
			type = 'tap';
		}

		// 绑定事件
		if (tool.isNodeList(element)) {
			[].forEach.call(element, function(item) {
				item.addEventListener(type, evt, false);
			})
		} else {
			element.addEventListener(type, evt, false);
		}
	},
};

var ui = {
	// 适用于页面只有下拉刷新，mui-slider-group不需要
	fixScroll: function(mtop) {
		//  mui-extend是必须的，否则会报错
		var $wrapper = $('.mui-scroll-wrapper');
		$wrapper.css('top',(document.querySelector('.mui-content').offsetHeight + (typeof(mtop)=="undefined"?15:mtop)) + 'px');
		var wrapperHeight = document.querySelector('.mui-scroll-wrapper').offsetHeight;
		$('.mui-scroll').css('min-height',wrapperHeight + 'px');
	},
	normalScroll: function(bounce, indicators) {
		bounce = typeof(bounce) == "undefined" ? true : bounce;
		indicators = typeof(indicators) == "undefined" ? false : indicators;
		var deceleration = mui.os.ios ? 0.003 : 0.0009;
		var scroller = mui('.mui-scroll-wrapper').scroll({
			bounce: bounce,
			indicators: indicators, //是否显示滚动条
			deceleration: deceleration
		});
		return scroller;
	},
	setPullToRefresh: function(scrollWrapper, scroll, evt, onlyPullDown) {
		// 页面只有一个滚动时可以省略前两个，否则应该传入
		if (tool.isFunction(scrollWrapper)) {
			evt = scrollWrapper;
			scrollWrapper = '.mui-scroll-wrapper';
			scroll = '.mui-scroll';
		}

		//阻尼系数
		var deceleration = mui.os.ios ? 0.003 : 0.0009;
		var scroller = mui(scrollWrapper).scroll({
			bounce: false,
			indicators: true, //是否显示滚动条
			deceleration: deceleration
		});
		var initObj = {};
		if (evt) initObj.down = {
			callback: function() {
				setTimeout(function() {
					evt(true);
				}, 100);
			}
		};
		if (!onlyPullDown && evt) initObj.up = {
			callback: function() {
				setTimeout(function() {
					evt();
				}, 100);
			}
		};
		var puller = mui(scroll).pullToRefresh(initObj);
		return {
			scroller: scroller,
			puller: puller
		};
	},
	clearScrollAnimal:function (puller, isRefresh, nomore) {
		if(isRefresh){
			if(puller.pullDownTips) {
				puller.endPullDownToRefresh(); // 停止下拉动画
			} 
			puller.refresh(true);
		}else{
			puller.endPullUpToRefresh(nomore);
			return;
		}
		
		if(nomore) {
			puller.endPullUpToRefresh(true); // 没有更多了
		}
	}
}

// ---------------------- 便捷数据存储及ajax封装 -------------------------------
/*
 * 数据访问
 */
var persistent = {
	uid: function() {
		return cache('uid');
	},
	utoken: function() {
		return cache('utoken');
	},
	uinfo: function() {
		var usrInfo = cache('uinfo');
		if (tool.isEmptyVal(usrInfo)) {
			return null;
		}
		return JSON.parse(usrInfo);
	},
}

var ajaxStatus = {
	OK: 200,
	ERROR: 300,
	FAIL_AUTH: 400,
	REFUSE: 500,
};

var _debug = false;
function debugLog (evtName,obj) {
	if(!_debug) return;
	console.log(JSON.stringify(obj));
	
	var logs = [];
	
	logs.push('--------------------'+evtName+'--------------------');
	if(Object.prototype.toString.call(obj) == "[object Array]"){
		obj.forEach(function (item) {
			logs.push(JSON.stringify(item));
		})
	}else if(Object.prototype.toString.call(obj) == "[object Object]"){
		for(var tmpKey in obj){
			logs.push("    "+tmpKey+': 【'+obj[tmpKey]+'】');
		}
	}
	logs.push('--------------------'+evtName+'--------------------');
	
	console.log(logs.join('\n'));
}

/*
 * 封装ajax
 */
var ajax = {
	getAuthHeader: function() {
		return persistent.uid() + ',' + persistent.utoken() + ','+plus.device.uuid+',' + 'sign';
	},
	post: function(url, paramObj, suc, wait, comp, err) {
		// 检测网络是否可用
		var network = plus.networkinfo.getCurrentType();
		if (network === plus.networkinfo.CONNECTION_UNKNOW ||
			network === plus.networkinfo.CONNECTION_NONE) {
			mui.toast(msg.NETWORK_IS_UNAVAILABLE);
			if (tool.isFunction(err)) err();
			if (tool.isFunction(comp)) comp();
			plus.nativeUI.closeWaiting(); // 默认关闭一下等待框，防止未处理情况下等待框无休止地转
			return;
		}

		if (tool.isObject(url)) {
			paramObj = url.paramObj;
			suc = url.suc;
			wait = url.wait;
			comp = url.comp;
			err = url.err;
			url = url.url;
		}

		// 显示等待框
		// if(typeof(wait)==="undefined") wait=true; // 设置默认是否显示
		wait = wait === null ? false : wait;
		if (wait) {
			plus.nativeUI.showWaiting();
		}
		paramObj = paramObj || {};
		// uri编码
		for (var k in paramObj) {
			var v = paramObj[k];
			if (!tool.isEmptyVal(v) && v.toString() === 'true')
				paramObj[k] = 'True';
			else if (!tool.isEmptyVal(v) && v.toString() === 'false')
				paramObj[k] = 'False';
			else if (tool.isString(v)) {
				v = v.replace(/\\/g, '\\\\');
				paramObj[k] = encodeURIComponent(v);
			}
		}

		var headerObj = {};
		headerObj.Authorization = this.getAuthHeader();
//		console.log(headerObj.Authorization);
		
		debugLog('before ajax',$.extend({},{url:url},headerObj,paramObj))
		
		// 发送请求
		mui.ajax(url, {
			type: 'POST',
			timeout: 30000,
			data: paramObj,
			dataType: 'json',
			headers: headerObj,
			success: function(data, textStatus, xhr) {
				debugLog('after ajax',data)
				if (data.StatusCode === ajaxStatus.OK) {
					if (tool.isFunction(suc)) suc(data, textStatus, xhr);
				} else if (data.StatusCode === ajaxStatus.ERROR) {
					var errMsg = data.Msg || msg.LOAD_DATA_FAIL;
					if (url === api.system.checkUpdate) {
						mui.alert(errMsg, msg.TITLE, 'OK', err);
						return;
					} else {
						plus.nativeUI.toast(errMsg);
						if (tool.isFunction(err)) err();
					}
				} else if (data.StatusCode === ajaxStatus.FAIL_AUTH) {
					var now = Date.parse(new Date());
					var old = cache('lastAuth');
					// 小于15秒，不重复跳转
					if (old && (now - parseInt(old)) < 15000) {
						if (tool.isFunction(err)) err();
						return;
					}
					cache('clear');
					cache('lastAuth', now);
					var uinfo = persistent.uinfo();
					if (uinfo) {
						var userName = uinfo.Username;
						cache('lastUser', userName);
					}
					plus.nativeUI.toast(msg.AUTH_EXPIRED);
					mui.fire(plus.webview.getLaunchWebview(), 'relogin');
					if (tool.isFunction(err)) err();
				} else {
					plus.nativeUI.toast(msg.SERVER_ERROR+'('+data.StatusCode+')');
					if (tool.isFunction(err)) err();
				}
			},
			error: function(xhr, type) {
//				console.log(xhr.responseText);
				if (type === 'parsererror') {
					plus.nativeUI.toast('Server response error');
				}else if(type === 'abort') {
					plus.nativeUI.toast(msg.LOAD_DATA_FAIL + "(" + type + ")");
//					console.log("ajax catch abort");
				}
				else {
//					console.log(url);
//					console.log(JSON.stringify(paramObj));
//					console.log(JSON.stringify(headerObj));
					plus.nativeUI.toast(msg.LOAD_DATA_FAIL + "(" + type + ")");
				}

				if (tool.isFunction(err)) err(xhr, type);
			},
			complete: function(status) {
				if (wait) plus.nativeUI.closeWaiting();
				if (tool.isFunction(comp)) comp(status);
				// 如果超时，强制关闭一下等待框，不然一直在转
				if (status === 'timeout') plus.nativeUI.closeWaiting();
			}
		});
	},
};